home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 2.0
-
- article- routines to read and display an article
-
-
- Copyright (C) 1991 John McCombs, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
- PO Box 2708, Christchurch, NEW ZEALAND
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
- Atari Version ported by Graham Judd - gjudd@siward.demon.co.uk
- */
-
- /*---------------------------- Source Control ------------------------------*/
-
- /*
- * $Id: ARTICLE.C,v 1.2 1994/02/05 18:46:56 gbj Exp user $
- */
-
- /****************************************************************************
- * 22 May 92 1.2 GT Fix "mail" and "reply" for ka9q. *
- * 31 May 92 1.3 GT Fix "Reply-To:" line. *
- * 03 Jun 92 1.4 GT Less vigorous quoting. *
- * 05 Jun 92 1.5 GT Fix author name parsing. *
- * 06 Jun 92 1.6 GT Invalidate freed pointers. *
- * Bigger buffer in "get_his_stuff". *
- * 08 Jun 92 1.7 GT FQDN in "Path:". *
- * 09 Jun 92 1.8 GT Right and left cursor keys. *
- * 12 Jun 92 1.9 NJL Half-way implement putting Date on header :-) *
- * Add configurable quotes and Organization: line. *
- * Ensure strtok() accepts tab as well as space. *
- * Stop down-arrow going past end of article. *
- * 26 Jun 92 1.10 GT Fix group name display format. *
- * 17 Jul 92 1.11 GT C++ compilation. *
- * Heap debugging. *
- * 16 Jul 92 1.12 MSM Snews 1.9 *
- * 21 Nov 92 1.13 MSM Empty Replyto line bug fixed *
- * 29 Dev 92 1.14 MSM Prevent null Organisation/Reply-to lines *
- * Fix bug in get_his_stuff returning rubbish *
- * Add current line count to article display *
- * Path: removed from mail messages *
- * 13 Feb 93 1.15 MSM Permit editing of full outgoing mail messages *
- * Enable editing of 'm'ail article to messages *
- * 6 Mar 93 1.16 MSM Prevent rude abort on 'out of memory' when *
- * reading an article. *
- * 2 Jun 93 1.17 MSM Snews 2.0 *
- * 18 Jun 93 1.18 MSM Heap debugging removed, now using Bounds Check *
- * 28 Jun 93 1.19 MSM Mail related items moved to mail.c *
- * 7 Aug 93 1.20 MSM Change commands to be more TIN'ish *
- * Add new command functions *
- * Expert mode *
- * 26 Sep 93 1.21 MSM Colour support clean up, Expert toggle, bugs *
- * 3 Oct 93 1.22 MSM Case sensitivity of y/n questions removed *
- * Old style tab action. *
- * Wide / long screen support corrected *
- * 25 Nov 93 1.23 MSM Minor header display changes *
- * 5 Dec 93 1.24 MSM Followup subject changed *
- * 2 Apr 94 1.25 MSM Correct 'K' prompt in non-expert mode *
- * Append/Replace/Exit options for save *
- * Article display wrapping at col x-1 *
- ****************************************************************************/
-
-
- #include "defs.h"
- #include "snews.h"
- #include "screen.h"
- #include "locking.h"
-
- #include <io.h>
- #include <ctype.h>
-
- #ifdef ATARI
- # include "st.h"
- # include "fileops.h"
- #endif
-
- #ifndef __TURBOC__
- #ifndef ATARI
- unsigned long farcoreleft(void);
- unsigned long testcoreleft(void);
- #define BLACK 0
- #define LIGHTGRAY 7
- #endif
- #endif
-
-
- int xfile2 = FALSE;
-
- extern char save_name[];
-
- char *empty_line = "\n";
-
- /*------------------------- read in an article -----------------------------*/
- TEXT *load_article(char *fnx, long offset, int warn)
- {
-
- /*
- * Open the file and read it. Save the author and organisation fill in the structures
- */
-
- FILE *tmp_file;
- char buf[BUFSIZ], lnbuf[BUFSIZ], hbuf[BUFSIZ], *p;
- TEXT *tx;
- LINES *ln, *lz;
- int ct, i, flag;
-
- tx = NULL;
- ct = 0;
- flag = 0;
-
- if ((tmp_file = fopen(fnx, "rb")) != NULL) {
-
- fseek(tmp_file, offset, SEEK_SET);
-
- tx = (TEXT *) malloc(sizeof(TEXT));
- tx->top = NULL;
- tx->start = NULL;
- tx->subject = NULL;
- tx->follow_up = NULL;
- tx->author = NULL;
- tx->organisation = NULL;
- tx->newsgroup = NULL;
- tx->distribution = NULL;
- tx->references = NULL;
- strcpy(tx->post_date, "");
-
- while (fgets(buf, sizeof(buf), tmp_file) != NULL) {
-
- if (strncmp(buf, "@@@@END\n", 7) == 0)
- break;
- #ifdef ATARI
- if (farcoreleft() < 2048) {
- #else
- #ifdef __TURBOC__
- if (farcoreleft() < 2048) {
- #else
- if (testcoreleft() < 2048) {
- #endif
- #endif
- if (warn == 0) {
- command("One or more articles partially skipped due to low memory");
- }
- else {
- message("Memory Low, only part article available, press any key");
- getch();
- }
- break;
- }
- expand_tabs(buf, sizeof(buf));
-
- /*
- * We now have a line of input. If the line is too long it
- * is wrapped at spaces, ',' or '!'. The lines of text are
- * stored in LINES structures
- */
- p = buf;
- while (strlen(p) > 0) {
-
- strcpy(lnbuf, p);
- strcpy(hbuf, p);
- if (hbuf[strlen(hbuf)-1] == '\n')
- hbuf[strlen(hbuf)-1] = '\0';
- if (strlen(p) <= scr_cols+1) {
- strcpy(lnbuf, p);
- *p = '\x00';
- }
- else {
- p += /*LINELENGTH*/scr_cols-1;
- for (i = /*LINELENGTH*/scr_cols-1; i > 50; i--) {
- if ((lnbuf[i] == ' ') || (lnbuf[i] == '!') || (lnbuf[i] == ',')) {
- if (lnbuf[i] != ' ') {
- i++;
- p++;
- }
- break;
- }
- p--;
- }
- lnbuf[i] = '\x00';
- }
-
- if (lnbuf[strlen(lnbuf) - 1] != '\n')
- strcat(lnbuf, "\n");
-
- /* is it the first line - if so int the TEXT structure */
- if (ct == 0) {
- ln = (LINES *) malloc(sizeof(LINES));
- ln->last = NULL;
- tx->top = ln;
- }
- else {
- lz = ln;
- ln->next = (LINES *) malloc(sizeof(LINES));
- ln = ln->next;
- ln->last = lz;
- }
- ln->next = NULL;
-
- lnbuf[/*LINELENGTH*/scr_cols/* + 1*/] = '\x00';
- ln->index = ct;
- if (lnbuf[0] == '\n')
- ln->data = empty_line;
- else {
- ln->data = (char *) malloc(strlen(lnbuf) + 1);
- strncpy(ln->data, lnbuf, strlen(lnbuf));
- ln->data[strlen(lnbuf)] = '\0';
- }
-
- if ((strlen(lnbuf) == 1) && (flag == 0) && (tx->start == NULL)) {
- flag = 1; /* Skip blank line at head */
- tx->start = ln; /* just in case there is is no body */
- }
- else
- if (flag == 1) {
- tx->start = ln;
- flag = 2;
- }
- ct++;
-
- /* save the header info */
- if ((tx->start == NULL) && (strnicmp("From:", lnbuf, 5) == 0)) {
- tx->author = (char *) malloc(strlen(hbuf)-4);
- strcpy(tx->author, hbuf+6);
- }
- if ((tx->start == NULL) &&
- ((strncmp("Organisation:", lnbuf, 13) == 0) ||
- (strncmp("Organization:", lnbuf, 13) == 0))) {
- tx->organisation = (char *) malloc(strlen(hbuf)-12);
- strcpy(tx->organisation, hbuf+14);
- }
- if ((tx->start == NULL) && (strnicmp("Followup-To:", lnbuf, 12) == 0)) {
- tx->follow_up = (char *) malloc(strlen(hbuf) - 11);
- strcpy(tx->follow_up, hbuf+13);
- }
- if ((tx->start == NULL) && (strnicmp("Newsgroups:", lnbuf, 11) == 0)) {
- tx->newsgroup = (char *) malloc(strlen(hbuf) - 10);
- strcpy(tx->newsgroup, hbuf+12);
- }
- if ((tx->start == NULL) && (strnicmp("Distribution:", lnbuf, 13) == 0)) {
- tx->distribution = (char *) malloc(strlen(hbuf) - 12);
- strcpy(tx->distribution, hbuf+14);
- }
- if ((tx->start == NULL) && (strnicmp("References:", lnbuf, 11) == 0)) {
- tx->references = (char *) malloc(strlen(hbuf) - 10);
- strcpy(tx->references, hbuf+12);
- }
- /* I want to display the article date, but dunno where :-) */
- if ((tx->start == NULL) && (strnicmp("Date:", lnbuf, 5) == 0)) {
- strcpy(tx->post_date, lnbuf+6);
- if (tx->post_date[(strlen(tx->post_date))-1] == '\n')
- tx->post_date[(strlen(tx->post_date))-1] = '\0';
- }
- if ((tx->start == NULL) && (strnicmp("Subject:", lnbuf, 8) == 0)) {
- tx->subject = (char *) malloc(strlen(hbuf) - 7);
- strcpy(tx->subject, hbuf + 9);
- }
- }
-
- }
-
- tx->lines = ct;
-
- fclose(tmp_file);
- }
- return (tx);
- }
-
-
- /*---------------------- deallocate article memory ------------------------*/
- void free_article(TEXT * t)
- {
-
- LINES *l, *k;
-
- l = t->top;
- while (l != NULL) {
- k = l;
- l = l->next;
- if (k->data != empty_line)
- free(k->data);
- k->data = NULL;
- free(k);
- k = NULL;
- }
-
- if (t->subject)
- free(t->subject);
- if (t->follow_up)
- free(t->follow_up);
- if (t->author)
- free(t->author);
- if (t->organisation)
- free(t->organisation);
- if (t->newsgroup)
- free(t->newsgroup);
- if (t->distribution)
- free(t->distribution);
- if (t->references)
- free(t->references);
- free(t);
- t = NULL;
- }
-
-
-
- /*---------------------------- read an article ----------------------------*/
- int read_article(ACTIVE * gp, TEXT * tx, ARTICLE *this_thread, int a_ct, ART_ID *id)
- {
-
- /*
- * This routine allows the user to read an article
- */
-
- LINES *this_art, *tmp; /* current thread */
- int exit_code; /* why we are exiting the loop */
- char sub_tmp[80];
-
- int ch, i, idx, ch2;
-
- this_art = tx->start;
- exit_code = 0;
- show_article(gp, tx, tx->subject, this_art, a_ct, this_thread->num_articles);
-
- while ((exit_code == 0) || (exit_code == EX_DUMMY)) {
-
- exit_code = 0;
- ch = getch();
- switch (ch) {
-
- case 0:
- case 0xE0:
- ch = getch();
-
- switch (ch) {
-
- case Fn1:
- show_help(HELP_ARTICLES);
- break;
-
- case Fn2:
- show_values();
- break;
-
- case Fn3:
- change_values();
- break;
-
- case UP_ARR:
- if (this_art->last != NULL) {
- this_art = this_art->last;
- gotoxy(1, TEXT_LINE + PAGE_LENGTH - 1);
- delline();
- gotoxy(1, TEXT_LINE);
- insline();
- clreol();
- cputs(this_art->data);
- }
- exit_code = EX_DUMMY;
- break;
-
- case DN_ARR:
- if (this_art->next != NULL) {
- tmp = this_art;
- for (i = 0; i < PAGE_LENGTH; i++) {
- if (tmp == NULL)
- break;
- tmp = tmp->next;
- }
- if (tmp != NULL) {
- this_art = this_art->next;
- gotoxy(1, TEXT_LINE);
- delline();
- gotoxy(1, TEXT_LINE + PAGE_LENGTH - 1);
- insline();
- clreol();
- cputs(tmp->data);
- }
- }
- exit_code = EX_DUMMY;
- break;
-
- case PGUP:
- if (this_art->last == NULL)
- exit_code = EX_DUMMY;
- else
- for (i = 0; i < PAGE_LENGTH-2; i++) {
- if (this_art->last == NULL)
- break;
- this_art = this_art->last;
- }
- break;
-
- case PGDN:
- if (this_art->next != NULL) {
- tmp = this_art;
- for (i = 0; i < PAGE_LENGTH; i++) {
- tmp = tmp->next;
- if (tmp == NULL)
- break;
- }
- if (tmp != NULL)
- this_art = tmp->last->last;
- else
- exit_code = EX_DUMMY;
- }
- break;
-
- case HOME:
- this_art = tx->start;
- break;
-
- case END:
- while (this_art->next != NULL)
- this_art = this_art->next;
- for (i = 0; i < PAGE_LENGTH - 1; i++) {
- if (this_art->last == NULL)
- break;
- this_art = this_art->last;
- }
- break;
-
- case LT_ARR:
- exit_code = (a_ct == 1) ? EX_QUIT : EX_PREV;
- exit_code |= EX_NOTREAD;
- break;
-
- case RT_ARR:
- exit_code = (a_ct == this_thread->num_articles) ? EX_DUMMY : (EX_NEXT | EX_NOTREAD);
- break;
-
- }
- break;
-
- case 2:
- case 21:
- case 'b':
- if (this_art->last == NULL)
- exit_code = EX_DUMMY;
- else
- for (i = 0; i < PAGE_LENGTH-2; i++) {
- if (this_art->last == NULL)
- break;
- this_art = this_art->last;
- }
- break;
-
- case 4:
- case 6:
- case ' ':
- if (this_art->next != NULL) {
- tmp = this_art;
- for (i = 0; i < PAGE_LENGTH; i++) {
- tmp = tmp->next;
- if (tmp == NULL)
- break;
- }
- if (tmp != NULL)
- this_art = tmp->last->last;
- else
- exit_code = EX_DUMMY;
- }
- break;
-
- case 8:
- this_art = tx->top;
- break;
-
- case 18: /* ^r */
- case 'g':
- this_art = tx->start;
- break;
-
- case '$':
- case 'G':
- while (this_art->next != NULL)
- this_art = this_art->next;
- for (i = 0; i < PAGE_LENGTH - 1; i++) {
- if (this_art->last == NULL)
- break;
- this_art = this_art->last;
- }
- break;
-
- case '!':
- textbackground(BLACK);
- textcolor(LIGHTGRAY);
- clrscr();
- #ifdef ATARI
- printf("Sorry, Shell function not supported. \n");
- printf("Press any key to return to Snews.\n");
- getch();
- #else
- printf("Type <EXIT> to return to Snews.\n\n");
- system("");
- #endif
- textbackground(textb);
- textcolor(textf);
- clrscr();
- break;
-
- case 'v':
- #ifdef ATARI
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d LC5 compiled %s", rmj, rmm, rup, __DATE__);
- #else
- #ifdef __TURBOC__
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d BC++ compiled %s", rmj, rmm, rup, __DATE__);
- #else
- sprintf(sub_tmp, "Demon Internet Simple News v%02d.%02d.%02d MSVC compiled %s", rmj, rmm, rup, __DATE__);
- #endif
- #endif
- message(sub_tmp);
- getch();
- break;
-
- case 'w':
- if (gp->suspend == TRUE)
- {
- message("This group is suspended, post regardless ? (y/n) ");
- ch2 = getch();
- ch2 = tolower(ch2);
- message("");
- }
- else
- ch2 = 'y';
- if (ch2 != 'y')
- break;
- strcpy(sub_tmp, "");
- post(NULL, gp->group, sub_tmp);
- break;
-
- case 'f':
- case 'F':
- if (gp->suspend == TRUE)
- {
- message("This group is suspended, post regardless ? (y/n) ");
- ch2 = getch();
- ch2 = tolower(ch2);
- message("");
- }
- else
- ch2 = 'y';
- if (ch2 != 'y')
- break;
- if (tx->follow_up == NULL)
- post(tx, gp->group, tx->subject);
- else if (strnicmp(tx->follow_up, "poster", 6) == 0) {
- message("Followup-To is to Poster, mail reply (y/n) - ");
- do
- {
- ch = getch();
- ch = tolower(ch);
- }
- while ((ch != 'y') && (ch != 'n'));
- if (ch == 'y')
- reply_to_article(tx, tx->subject);
- else
- post(tx, gp->group, tx->subject);
- }
- else {
- post(tx, tx->follow_up, tx->subject);
- }
- break;
-
- case 'r':
- reply_to_article(tx, this_thread->header);
- break;
-
- case 'R':
- ReplyAddress(tx, this_thread->header);
- break;
-
- case 'm':
- mail_to_someone(tx);
- break;
-
- case 'M':
- mail_to_someone(NULL);
- break;
-
- case 's':
- xfile2 = FALSE;
- save_to_disk(gp, id->art_off);
- message("-- Done --");
- break;
-
- case 'S':
- xfile2 = TRUE;
- save_to_disk(gp, id->art_off);
- xfile2 = FALSE;
- message("-- Done --");
- break;
-
- case 'd':
- rot13(tx);
- break;
-
- case 'o':
- print_article(gp, id->art_off);
- message("-- Done --");
- break;
-
- case 'h':
- case 'H':
- show_help(HELP_ARTICLES);
- break;
-
- case 'K':
- if (mark_thread_as_read(gp, this_thread, FALSE) == TRUE) {
- exit_code = EX_NEXT_UNREAD;
- }
- break;
-
- case 'N':
- exit_code = EX_NEXT_UNREAD;
- break;
-
- case 'z':
- idx = (int) ((id->id) - gp->lo_num - 1);
- *((gp->read_list) + idx) = (char) FALSE;
- exit_code = (EX_NEXT | EX_NOTREAD);
- break;
-
- case 'n':
- case 'k':
- exit_code = EX_NEXT;
- break;
-
- case '<':
- exit_code = EX_FIRST;
- break;
-
- case '>':
- exit_code = EX_LAST;
- break;
-
- case TAB:
- if (my_stuff.tab_action == TRUE) {
- if (this_art->next != NULL) {
- tmp = this_art;
- for (i=0;i< PAGE_LENGTH; i++) {
- tmp = tmp->next;
- if (tmp == NULL)
- break;
- }
- if ((tmp != NULL) && (i > 2)) {
- this_art = tmp->last->last;
- while (tmp != NULL) {
- if (tmp->data[0] != '\n')
- break;
- tmp = tmp->next;
- }
- #ifdef ATARI
- if (tmp == NULL)
- exit_code=EX_NEXT_UNREAD;
- else if ((tmp->data)[0] == '\n')
- exit_code = EX_NEXT_UNREAD;
- #else
- if (((tmp->data)[0] == '\n') || (tmp == NULL))
- exit_code = EX_NEXT_UNREAD;
- #endif
- }
- else
- exit_code = EX_NEXT_UNREAD;
- }
- else
- exit_code = EX_NEXT_UNREAD;
- break;
- }
- else { /* old style tab action */
- exit_code = EX_NEXT_UNREAD;
- break;
- }
-
- case ENTER:
- exit_code = EX_NEXT;
- break;
-
- case ESCAPE:
- case 'q':
- case 'Q':
- case 'T':
- exit_code = EX_QUIT;
- exit_code |= EX_NOTREAD;
- break;
-
- case 'p':
- exit_code = EX_PREVIOUS;
- break;
-
- case '+':
- case '=':
- case '/':
- exit_code = EX_SEARCH_FORW;
- exit_code |= EX_NOTREAD;
- break;
-
- case '-':
- case '?':
- exit_code = EX_SEARCH_BACKW;
- exit_code |= EX_NOTREAD;
- break;
-
- case 'B':
- bug_report();
- show_article(gp, tx, tx->subject, this_art, a_ct, this_thread->num_articles);
-
- default:
- exit_code = EX_DUMMY;
- break;
- }
-
- if (exit_code == 0)
- show_article(gp, tx, tx->subject, this_art, a_ct, this_thread->num_articles);
- else {
- gotoxy(scr_cols-16, 2);
- textbackground(headb);
- textcolor(headf);
- cprintf("%4d", this_art->index + 1);
- textbackground(textb);
- textcolor(textf);
- }
- }
-
- return (exit_code);
- }
-
-
-
- /*--------------------------- show the article ----------------------------*/
- void show_article(ACTIVE * gp, TEXT * tx, char *subject, LINES * this_art, int a_ct,
- int of_ct)
- {
-
- /*
- * This routine show a page of an article
- */
-
- int i, j;
- char buf[512];
- #ifdef ATARI
- int alen, olen;
- #endif
-
- clrscr();
-
- textbackground(headb);
- textcolor(headf);
-
- #ifdef ATARI
- for (i=0; i < 4; i++)
- printf("%*s", scr_cols, " ");
- #else
- clreol();
- #endif
- if (strnicmp(gp->group, "junk", 4) == 0) {
- if ((strlen(tx->newsgroup) <= 30) && (tx->newsgroup[strlen(tx->newsgroup)-1] == '\n'))
- tx->newsgroup[strlen(tx->newsgroup)-1] = '\0';
- strcpy(buf, "");
- j = 16 - (strlen(tx->newsgroup)/2);
- if (j>1) {
- for (i=0;i<j;i++)
- strcat(buf, " ");
- }
- strcat(buf, tx->newsgroup);
- gotoxy(1, 1);
- cprintf("%-25.25s", tx->post_date);
- gotoxy((scr_cols/2) - 16, 1);
- cprintf("%-31.31s", buf);
- gotoxy(scr_cols-22, 1);
- cprintf("Article: %4d of %4d\r\n", a_ct, of_ct);
- }
- else {
- strcpy(buf, "");
- j = 16 - (strlen(gp->group)/2);
- if (j>1) {
- for (i=0;i<j;i++)
- strcat(buf, " ");
- }
- strcat(buf, gp->group);
- gotoxy(1, 1);
- cprintf("%-25.25s", tx->post_date);
- gotoxy((scr_cols/2) - 16, 1);
- cprintf("%-31.31s", buf);
- gotoxy(scr_cols-22, 1);
- cprintf("Article: %4d of %4d\r\n", a_ct, of_ct);
- }
- #ifndef ATARI
- clreol();
- #endif
- strncpy(buf, subject, 58);
- if ((strlen(buf) <= 49) && (buf[strlen(buf)-1] == '\n'))
- buf[strlen(buf)-1] = '\x00';
- else
- buf[49] = '\x00';
-
- cprintf("Subject: %-50.50s\r\n", buf);
- gotoxy(scr_cols-16, 2);
- cprintf("%4d / %4d lines\r\n", this_art->index + 1, tx->lines);
- #ifndef ATARI
- clreol();
- #endif
-
- #ifdef ATARI
- if (tx->author)
- alen=strlen(tx->author);
- else
- alen=0;
- if (tx->organisation)
- olen=strlen(tx->organisation);
- else
- olen=0;
- #endif
-
- #ifdef ATARI
- if (alen + olen > (size_t)(scr_cols-10))
- #else
- if (strlen(tx->author) + strlen(tx->organisation) > (size_t)(scr_cols-10))
- #endif
- {
- #ifdef ATARI
- if (alen > olen)
- #else
- if (strlen(tx->author) > strlen(tx->organisation))
- #endif
- {
- #ifdef ATARI
- i = (scr_cols - 10) - olen;
- #else
- i = (scr_cols - 10) - strlen(tx->organisation);
- #endif
- if (i < (scr_cols-10)/2)
- i = (scr_cols-10)/2;
- if (tx->author == NULL)
- strcpy(buf, "Unknown");
- else
- strncpy(buf, tx->author, i);
- buf[i] = '\0';
- strcat(buf, " at ");
- if (tx->organisation == NULL)
- strcat(buf, "(none)");
- else
- strncat(buf, tx->organisation, (scr_cols-10)-i);
- buf[(scr_cols-10)] = '\0';
- }
- else
- {
- #ifdef ATARI
- i = (scr_cols-10) - alen;
- #else
- i = (scr_cols-10) - strlen(tx->author);
- #endif
- if (i < (scr_cols-10)/2)
- i = (scr_cols-10)/2;
- if (tx->author == NULL)
- strcpy(buf, "Unknown");
- else
- strncpy(buf, tx->author, (scr_cols-12)-i);
- buf[(scr_cols-12)-i] = '\0';
- strcat(buf, " at ");
- if (tx->organisation == NULL)
- strcat(buf, "(none)");
- else
- strncat(buf, tx->organisation, i);
- buf[(scr_cols-10)] = '\0';
- }
- }
- else
- {
- if (tx->author == NULL)
- strcpy(buf, "Unknown");
- else
- strcpy(buf, tx->author);
- strcat(buf, " at ");
- if (tx->organisation == NULL) {
- if (strlen(buf) > (size_t) scr_cols-17)
- buf[scr_cols-17] = '\0';
- strcat(buf, "(none)");
- }
- else
- strcat(buf, tx->organisation);
- }
- cprintf("From: %s", buf);
- textbackground(textb);
- textcolor(textf);
-
-
- gotoxy(1, TEXT_LINE);
- for (i = 0; i < PAGE_LENGTH; i++) {
- gotoxy(1, i + TEXT_LINE);
- cputs(this_art->data);
- this_art = this_art->next;
- if (this_art == NULL)
- break;
- }
-
- sprintf(buf, "ESC=select thread TAB=next ENTER=next article F1 or 'h'=help [%ldk]",
- farcoreleft()/1024);
- command(buf);
- }
-
-
-
- /*-------------------------- save article --------------------------------*/
- void save_to_disk(ACTIVE *gp, long offset)
- {
-
- /*
- * This routine saves an article to disk, appending if necessary
- */
-
- FILE *tmp = NULL, *tmp_file;
- char fn[80];
- int ch;
- char *fnx;
- time_t now;
- struct tm *tmnow;
- char timestr[64], prompt[128];
- char buf[512];
-
- if (xfile2 == TRUE) {
- strcpy(fn, my_stuff.mail_dir);
- strcat(fn, my_stuff.extruser);
- strcat(fn, ".txt");
- }
- else {
- sprintf(prompt, "Enter filename? [%s] ", save_name);
- lmessage(prompt);
- gets(fn);
- if (strlen(fn) > 0)
- strcpy(save_name, fn);
- else
- strcpy(fn, save_name);
- }
-
- if (access(fn, 0) == 0) {
- if (xfile2 == TRUE) {
- if ((tmp = fopen(fn, "at")) == NULL) {
- message("*** Cannot open file for appending - "
- "press any key to continue ***");
- getch();
- }
- }
- else {
- message("File exists - append/replace/exit(a/r/e)? ");
- do
- {
- ch = getch();
- ch = tolower(ch);
- }
- while ((ch != 'a') && (ch != 'r') && (ch != 'e'));
- if (ch == 'e') {
- message("*** Save aborted - press any key to continue ***");
- getch();
- return;
- }
- if (ch == 'a') {
- if ((tmp = fopen(fn, "at")) == NULL) {
- message("*** Cannot open file for appending - press any key to continue ***");
- getch();
- }
- }
- else {
- if ((tmp = fopen(fn, "wt")) == NULL) {
- message("*** Cannot open file for output - press any key to continue ***");
- getch();
- }
- }
- }
-
- }
- else {
-
- if ((tmp = fopen(fn, "wt")) == NULL) {
- message("*** Cannot open file for output - press a key to continue ***");
- getch();
- }
- }
-
- if (tmp != NULL) {
-
- fnx = make_news_group_name(gp->group);
-
- if (xfile2 == TRUE) {
- tzset();
- time(&now);
- tmnow = localtime(&now);
- strftime(timestr, sizeof(timestr), "%a %b %d %H:%M:%S %Z %Y", tmnow);
- fprintf(tmp, "From snews@%s.%s %s\n", my_stuff.my_site,
- my_stuff.my_domain, timestr);
- }
-
- if ((tmp_file = fopen(fnx, "rb")) != NULL) {
-
- fseek(tmp_file, offset, SEEK_SET);
- while (fgets(buf, sizeof(buf), tmp_file) != NULL) {
- if (strncmp(buf, "@@@@END\n", 7) == 0)
- break;
- fputs(buf, tmp);
- }
- fclose(tmp_file);
- }
- fclose(tmp);
- }
- }
-
- /*-------------------------- print article --------------------------------*/
- void print_article(ACTIVE *gp, long offset)
- {
-
- /*
- * This routine prints an article
- */
-
- FILE *tmp_file;
- char *fnx;
- char buf[512];
-
- strcpy(save_name, "prn");
-
-
-
- fnx = make_news_group_name(gp->group);
-
- if ((tmp_file = fopen(fnx, "rb")) != NULL) {
-
- fseek(tmp_file, offset, SEEK_SET);
- while (fgets(buf, sizeof(buf), tmp_file) != NULL) {
- if (strncmp(buf, "@@@@END\n", 7) == 0)
- break;
- fputs(buf, stdprn);
- fputc(0x0d, stdprn);
- }
- fputc(0x0c, stdprn);
- fflush(stdprn);
- fclose(tmp_file);
- }
-
- }
-
- /*----------------------- get stuff off article header --------------------*/
- void get_his_stuff(TEXT * tx, char *author, char *msg_id, char *r_name)
- {
-
- /*
- * Retrieve the author and msg_id from the article
- */
-
- LINES *ln;
- char *p, *q;
- char buf[BUFSIZ];
- char *null_name = {" ** none ** "};
-
- DBGOUT(("%s:%d\n", __FILE__, __LINE__));
- strcpy(author, null_name);
- strcpy(msg_id, " <none> ");
- strcpy(r_name, "");
-
- ln = tx->top;
- while (ln != NULL) {
- strncpy(buf, ln->data, sizeof(buf));
- *(buf + sizeof(buf) - 1) = '\0';
- p = strtok(buf, " \t:\n\r");
- p = strtok(NULL, " \t:\n\r");
-
- if (strnicmp(ln->data, "Message-ID:", 11) == 0) {
- if (p != NULL)
- strcpy(msg_id, p);
- }
-
- if ((strnicmp(ln->data, "From:", 5) == 0) &&
- (strcmp(author, null_name) == 0)) {
- if ((q = strchr(ln->data, '<')) != NULL) {
- strcpy(buf, ln->data);
- q = strchr(buf, '<');
- *(q-1) = '\0';
- if (*(buf+6) == '\"') {
- strcpy(r_name, buf+6);
- }
- else {
- strcpy(r_name, "\"");
- strcat(r_name, buf+6);
- strcat(r_name, "\"");
- }
- q++;
- p = strtok(q, ">");
- }
- if (p != NULL)
- strcpy(author, p);
-
- p = NULL;
- if ((q = strchr(ln->data, '(')) != NULL) {
- strcpy(buf, ln->data);
- q = strchr(buf, '(');
- q++;
- p = strtok(q, ")");
- if (p != NULL) {
- if (*p == '\"') {
- strcpy(r_name, p);
- }
- else {
- strcpy(r_name, "\"");
- strcat(r_name, p);
- strcat(r_name, "\"");
- }
- }
- }
- }
-
- if (strnicmp(ln->data, "Reply-To:", 9) == 0) {
- if ((q = strchr(ln->data, '<')) != NULL) {
- strcpy(buf, ln->data);
- q = strchr(buf, '<');
- q++;
- p = strtok(q, ">");
- }
- if (p != NULL)
- strcpy(author, p);
- }
-
- if (strlen(ln->data) < 2)
- break;
- ln = ln->next;
- }
-
- }
-
-
- /*--------------------------- rot 13 the article ------------------------*/
- void rot13(TEXT * tx)
- {
- LINES *ln;
- int i, c;
-
-
- ln = tx->start;
-
- while (ln != NULL) {
- for (i = 0; i < (int)(strlen(ln->data)); i++) {
- c = *((ln->data) + i);
- if ((c >= 'A') && (c <= 'Z')) {
- *((ln->data) + i) = (((c - 'A') + 13) % 26) + 'A';
- }
- else {
- if ((c >= 'a') && (c <= 'z')) {
- *((ln->data) + i) = (((c - 'a') + 13) % 26) + 'a';
- }
- }
- }
- ln = ln->next;
- }
- }
-
-
- /*--------------------------- expand the tabs ----------------------------*/
- void expand_tabs(char *buf, int max_len)
- {
- int l, k;
- char tmp[BUFSIZ], *p, *t;
-
- p = buf;
- t = &tmp[0];
- l = 0;
-
- while ((*p != '\x00') && (l < max_len)) {
- if (*p != '\x09') {
- *t = *p;
- t++;
- p++;
- l++;
- }
- else {
- p++;
- k = ((l / 8) + 1) * 8;
- for (; l < k; l++) {
- *t = ' ';
- t++;
- if (l >= max_len)
- break;
- }
- }
- }
-
- *t = '\x00';
- strcpy(buf, tmp);
- }
-